package javawdw.picture.core;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;

import javawdw.picture.api.Picture;
import javawdw.picture.util.PictureSpliter;

/**
 * 静态图片
 * 
 * @author David
 * 
 */
public class Frame implements Picture {
	private BufferedImage image;

	private int width;
	private int height;

	private Frame() {

	}

	/**
	 * 获得图片宽度
	 * 
	 * @return 返回图片宽度
	 */
	public int getWidth() {
		return this.width;
	}

	/**
	 * 获得图片高度
	 * 
	 * @return 返回图片高度
	 */
	public int getHeight() {
		return this.height;
	}

	/**
	 * 在当前图片的指定位置添加另一张图片
	 * 
	 * @param picture
	 *            要添加的图片
	 * @param position
	 *            添加图片的位置
	 * @param transparency
	 *            透明度(0~1,1为不透明)
	 */
	public void draw(Picture picture, Position position) {
		this.draw(picture, position, 1);
	}

	/**
	 * 在当前图片的指定位置添加另一张图片
	 * 
	 * @param picture
	 *            要添加的图片
	 * @param position
	 *            添加图片的位置
	 * @param transparency
	 *            透明度(0~1,1为不透明)
	 */
	public void draw(Picture picture, Position position, double transparency) {
		Graphics2D graphics2D = this.image.createGraphics();
		graphics2D.setComposite(AlphaComposite.getInstance(
				AlphaComposite.SRC_ATOP, (float) transparency));
		int width_biao = picture.getWidth();
		int height_biao = picture.getHeight();
		int x = position.getX();
		int y = position.getY();
		Frame staticImage = PictureSpliter.getFirstFrame(picture);
		if (staticImage != null && staticImage.image != null) {
			graphics2D.drawImage(staticImage.image, x, y, width_biao,
					height_biao, null);
		}
		graphics2D.dispose();
	}

	/**
	 * 在当前图片的指定位置添加字符串
	 * 
	 * @param content
	 *            要添加文字的内容
	 * @param style
	 *            字体信息
	 * @param position
	 *            要添加文字的位置
	 */
	public void draw(String content, TextStyle style, Position position) {
		this.draw(content, style, position, 1);
	}

	/**
	 * 在当前图片的指定位置添加字符串
	 * 
	 * @param content
	 *            要添加文字的内容
	 * @param style
	 *            字体信息
	 * @param position
	 *            要添加文字的位置
	 * @param transparency
	 *            透明度(0~1,1为不透明)
	 */
	public void draw(String content, TextStyle style, Position position,
			double transparency) {
		Graphics2D graphics2D = this.image.createGraphics();
		graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		graphics2D.setFont(style.getFont());
		graphics2D.setColor(style.getFontColor());
		graphics2D.setComposite(AlphaComposite.getInstance(
				AlphaComposite.SRC_ATOP, (float) transparency));
		int x = position.getX();
		int y = position.getY();
		graphics2D.drawString(content, x, y + style.getFontSize() - 3);
		graphics2D.dispose();
	}

	/**
	 * 根据指定高度和宽度、颜色画出指定区域
	 * 
	 * @param width
	 *            给定的宽度
	 * @param height
	 *            给定的高度
	 * @param bgColor
	 *            给定的颜色
	 * @return 返回画出的图片
	 */
	public static Frame drawBlank(int width, int height, Color bgColor) {
		BufferedImage resultImage = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);
		Graphics2D graphics = resultImage.createGraphics();
		graphics.setColor(bgColor);
		graphics.fillRect(0, 0, width, height);
		graphics.dispose();
		Frame frame = new Frame();
		frame.image = resultImage;
		return frame;
	}

	/**
	 * 根据指定的高度和宽度画出透明区域
	 * 
	 * @param width
	 *            给定的宽度
	 * @param height
	 *            给定的高度
	 * @return 返回画出的图片
	 */
	public static Frame drawNoColor(int width, int height) {
		BufferedImage resultImage = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);
		Graphics2D graphics = resultImage.createGraphics();
		GraphicsConfiguration con = graphics.getDeviceConfiguration();
		resultImage = con.createCompatibleImage(width, height,
				Transparency.TRANSLUCENT);
		graphics.dispose();
		Frame frame = new Frame();
		frame.image = resultImage;
		return frame;
	}

	/**
	 * 根据给定横向、纵向比率缩放图片
	 * 
	 * @param ratioX
	 *            给定横向比率
	 * @param ratioY
	 *            给定纵向比率
	 */
	public void zoom(double ratioX, double ratioY) {
		AffineTransform affineTransform = AffineTransform.getScaleInstance(
				ratioX, ratioY);
		AffineTransformOp op = new AffineTransformOp(affineTransform,
				AffineTransformOp.TYPE_BICUBIC);
		this.image = op.filter(this.image, null);
	}

	/**
	 * 根据开始坐标点、宽、高裁剪图片
	 * 
	 * @param startPosition
	 *            给定的开始坐标点
	 * @param newWidth
	 *            给定的宽度
	 * @param newHeight
	 *            给定的高度
	 */
	public void crop(Position startPosition, int newWidth, int newHeight) {
		int x = startPosition.getX();
		int y = startPosition.getY();
		BufferedImage resultImage = new BufferedImage(newWidth, newHeight,
				BufferedImage.TYPE_INT_RGB);
		Graphics2D graphics2D = resultImage.createGraphics();
		if (x + newWidth > this.getWidth()) {
			newWidth = this.getWidth() - x;
		}
		if (y + newHeight > this.getHeight()) {
			newHeight = this.getHeight() - y;
		}
		BufferedImage temp = this.image.getSubimage(x, y, newWidth, newHeight);
		graphics2D.drawImage(temp, 0, 0, null);
		graphics2D.dispose();
		this.image = resultImage;
	}

	/**
	 * 根据角度和生成图片的宽度、高度以图片中心为原点旋转图片
	 * 
	 * @param degree
	 *            给定的角度
	 * @param newWidth
	 *            给定的宽度
	 * @param newHeight
	 *            给定的高度
	 */
	public void revolve(double degree, int newWidth, int newHeight) {
		BufferedImage resultImage = new BufferedImage(newWidth, newHeight,
				BufferedImage.TYPE_INT_RGB);
		Graphics2D graphics2D = resultImage.createGraphics();
		graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		graphics2D.rotate(Math.toRadians(degree), newWidth / 2, newHeight / 2);
		graphics2D.drawImage(this.image, 0, 0, null);
		graphics2D.dispose();
		this.image = resultImage;
	}

	/**
	 * 复制图片
	 * 
	 * @return 复制得到的图片
	 */
	public Frame clone() {
		BufferedImage resultImage = new BufferedImage(this.getWidth(), this
				.getHeight(), BufferedImage.TYPE_INT_RGB);
		Graphics2D graphics2D = resultImage.createGraphics();
		graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		graphics2D.drawImage(this.image, 0, 0, null);
		graphics2D.dispose();
		Frame frame = new Frame();
		frame.image = resultImage;
		return frame;
	}
}